package com.aiti.lulian.service.newCard;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.WorkbookUtil;
import com.aiti.base.core.exception.BusinessException;
import com.aiti.base.core.page.PageInfo;
import com.aiti.base.core.page.PageResult;
import com.aiti.base.core.utils.message.Message;
import com.aiti.base.core.utils.uuid.UUIDUtil;
import com.aiti.lulian.dto.newCard.CardAdminExportRecordDto;
import com.aiti.lulian.dto.newCard.CardBaseInfoDto;
import com.aiti.lulian.dto.newCard.CardTemplateStyleFieldBo;
import com.aiti.lulian.dto.newCard.CardUserManagementDto;
import com.aiti.lulian.entity.CardEnterpriseTemplate;
import com.aiti.lulian.entity.LuLianEnterprise;
import com.aiti.lulian.entity.LuLianEnterpriseUser;
import com.aiti.lulian.entity.excel.CardUserManagementExport;
import com.aiti.lulian.entity.newCard.*;
import com.aiti.lulian.gxmh.entity.GxmhEnterpriseLinkCount;
import com.aiti.lulian.handler.HeaderStyleHandler;
import com.aiti.lulian.mapper.*;
import com.aiti.lulian.mapper.gxmh.GxmhEnterpriseLinkCountMapper;
import com.aiti.lulian.mapper.newCard.*;
import com.aiti.lulian.service.ILuLianEnterpriseService;
import com.aiti.lulian.utils.Md5Util;
import com.aiti.lulian.utils.ResponseUtil;
import com.aiti.lulian.vo.CardEnterpriseTemplateVo;
import com.aiti.lulian.vo.newCard.CardMemberDataVo;
import com.aiti.lulian.vo.newCard.CardUserManagementVo;
import com.aiti.lulian.vo.newCard.CardUserTemplateVo;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CardAdminBackendService {

    private static final String MUST_FILL = "（必填）";
    @Autowired
    private CardAdminBackendMapper cardAdminBackendMapper;
    @Autowired
    private CardAdminListFieldConfigMapper cardAdminListFieldConfigMapper;
    @Autowired
    private ShowEnterpriseTrialMapper showEnterpriseTrialMapper;
    @Autowired
    private CardPersonalBaseInfoMapper cardPersonalBaseInfoMapper;
    @Autowired
    private LuLianEnterpriseMapper luLianEnterpriseMapper;
    @Autowired
    private ILuLianEnterpriseService luLianEnterpriseService;
    @Autowired
    private CardEnterpriseTemplateNewMapper cardEnterpriseTemplateNewMapper;
    @Autowired
    private CardEnterpriseComponentMapper cardEnterpriseComponentMapper;
    @Autowired
    private LuLianEnterpriseUserMapper luLianEnterpriseUserMapper;
    @Autowired
    private GxmhEnterpriseLinkCountMapper gxmhEnterpriseLinkCountMapper;
    @Autowired
    private CardEnterpriseTemplateMapper cardEnterpriseTemplateMapper;
    @Autowired
    private CardTemplateStyleFieldMapper cardTemplateStyleFieldMapper;
    @Autowired
    private CardStyleFieldDataMapper cardStyleFieldDataMapper;
    @Autowired
    private CardAdminExportRecordMapper cardAdminExportRecordMapper;
    @Autowired
    private CardUserCardSettingMapper cardUserCardSettingMapper;

    public Message getUserManagementPage(CardUserManagementDto dto) {
        // 对传参进行预处理
        if (StrUtil.isNotBlank(dto.getCounty())) {
            dto.setCity(null);
            dto.setProvince(null);
        } else if (StrUtil.isNotBlank(dto.getCity())) {
            dto.setProvince(null);
        }

        // 获取所有数据
        List<CardUserManagementVo> allData = cardAdminBackendMapper.selectUserManagementPage(dto);
        Integer pageNum = dto.getPageNum();
        Integer pageSize = dto.getPageSize();
        if ((pageNum == null || pageSize == null) || (pageNum == 0 && pageSize == 10)) {
            return Message.success(allData);
        }

        // 应用程序层手动实现分页，数据量过大时应尽快优化
        int total = allData.size();
        int fromIndex = (pageNum - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);

        if (fromIndex > total) {
            return Message.success(new PageResult<>(Collections.emptyList(), new PageInfo(pageNum, pageSize), total));
        }

        List<CardUserManagementVo> resultList = allData.subList(fromIndex, toIndex);
        return Message.success(new PageResult<>(resultList, new PageInfo(pageNum, pageSize), total));
    }

    public void exportUserData(HttpServletResponse response, CardUserManagementDto dto) throws IOException {
        Message userManagementPage = this.getUserManagementPage(dto);
        List<CardUserManagementVo> dataList = (List<CardUserManagementVo>) userManagementPage.getObj();
        if (dto.getBaseIdList() != null && !dto.getBaseIdList().isEmpty()) {
            dataList = dataList.stream().filter(i -> dto.getBaseIdList().contains(i.getBaseId())).collect(Collectors.toList());
        }
        List<CardUserManagementExport> exportList = dataList.stream().map(i -> {
            CardUserManagementExport cardUserManagementExport = new CardUserManagementExport();
            BeanUtils.copyProperties(i, cardUserManagementExport);
            return cardUserManagementExport;
        }).collect(Collectors.toList());

        // 根据当前登录人查询其配置好的列表展示字段
        List<String> fieldNameList = cardAdminListFieldConfigMapper.selectFieldNameList(dto.getUserId());
        if (fieldNameList == null || fieldNameList.isEmpty()) {
            // 若登录人没有进行过自定义配置，则使用默认的配置
            fieldNameList = cardAdminListFieldConfigMapper.selectFieldNameList("1");
        }
        Set<String> includeColumnFieldNames = new HashSet<>(fieldNameList);

        // 设置响应头，确保浏览器以下载方式处理文件
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");

        // 设置文件名，注意需要对中文进行 URL 编码
        String fileName = URLEncoder.encode("用户数据", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + ".xlsx\";" + " filename*=UTF-8''" + fileName + ".xlsx");

        // 使用 EasyExcel 写入数据到输出流
        OutputStream outputStream =  response.getOutputStream();
        EasyExcel.write(outputStream, CardUserManagementExport.class)
                .includeColumnFiledNames(includeColumnFieldNames)
                .sheet("用户数据")
                .registerWriteHandler(new HeaderStyleHandler())
                .doWrite(exportList);

        // 关闭流资源
        if (outputStream != null) {
            outputStream.close();
        }
    }

    @Transactional(rollbackFor = Throwable.class)
    public Message updateUserDataBatch(CardUserManagementDto dto) throws ParseException {
        List<CardUserManagementVo> paramList = dto.getParamList();
        for (CardUserManagementVo param : paramList) {
            Integer backendVersion = param.getBackendVersion();
            if (backendVersion == 1 || backendVersion == 2 || backendVersion == 3) {
                // 个人版、个人试用版和个人付费版（名片版）不可以修改过期时间
                throw new BusinessException("个人版、个人试用版和名片版不可修改过期时间");
            } else if (backendVersion == 4) {
                // 企业试用版
                ShowEnterpriseTrial showEnterpriseTrial = showEnterpriseTrialMapper.selectById(param.getBaseId());
                if (showEnterpriseTrial == null || "1".equals(showEnterpriseTrial.getIsDelete())) {
                    throw new BusinessException("试用企业( "+ param.getBaseId() +")不存在");
                }
                showEnterpriseTrialMapper.update(null, new LambdaUpdateWrapper<ShowEnterpriseTrial>().eq(ShowEnterpriseTrial::getBaseId, param.getBaseId()).set(ShowEnterpriseTrial::getExpireTime, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dto.getExpireTime())));
                cardPersonalBaseInfoMapper.update(null, new LambdaUpdateWrapper<CardBaseInfo>().eq(CardBaseInfo::getEnterpriseId, param.getBaseId()).eq(CardBaseInfo::getCardVersion, "2").set(CardBaseInfo::getExpireTime, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dto.getExpireTime())));
            } else if (backendVersion == 5 || backendVersion == 6 || backendVersion == 7) {
                // 企业基础版、企业高级版、企业拓客版
                LuLianEnterprise luLianEnterprise = luLianEnterpriseMapper.selectById(param.getBaseId());
                if (luLianEnterprise == null || "1".equals(luLianEnterprise.getIsDelete())) {
                    throw new BusinessException("企业( "+ param.getBaseId() +")不存在");
                }
                luLianEnterpriseService.update(new LambdaUpdateWrapper<LuLianEnterprise>().eq(LuLianEnterprise::getBaseId, param.getBaseId()).set(LuLianEnterprise::getExpireTime, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dto.getExpireTime())));
                cardPersonalBaseInfoMapper.update(null, new LambdaUpdateWrapper<CardBaseInfo>().eq(CardBaseInfo::getEnterpriseId, param.getBaseId()).in(CardBaseInfo::getCardVersion, "3", "4", "5").set(CardBaseInfo::getExpireTime, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dto.getExpireTime())));
            } else {
                throw new BusinessException("无效的版本信息");
            }
        }
        return Message.success("操作成功");
    }

    public Message getEnterpriseAllQualifications(String enterpriseId) {
        List<CardEnterpriseTemplateNew> cardEnterpriseTemplateNews = cardEnterpriseTemplateNewMapper.selectList(new LambdaQueryWrapper<CardEnterpriseTemplateNew>().eq(CardEnterpriseTemplateNew::getEnterpriseId, enterpriseId).eq(CardEnterpriseTemplateNew::getIsDelete, 0));
        if (cardEnterpriseTemplateNews.isEmpty()) {
            return Message.success(new ArrayList<>());
        }
        List<CardEnterpriseComponent> enterpriseQualifications = cardEnterpriseComponentMapper.selectList(new LambdaQueryWrapper<CardEnterpriseComponent>().in(CardEnterpriseComponent::getTemplateId, cardEnterpriseTemplateNews.stream().map(CardEnterpriseTemplateNew::getBaseId).collect(Collectors.toList())).eq(CardEnterpriseComponent::getComponentType, "EnterpriseQualification").orderByAsc(CardEnterpriseComponent::getSort));
        if (enterpriseQualifications.isEmpty()) {
            return Message.success(new ArrayList<>());
        }
        List<EnterpriseHonor> picList = new ArrayList<>();
        for (CardEnterpriseComponent enterpriseQualification : enterpriseQualifications) {
            String componentMetaData = enterpriseQualification.getComponentMetaData();
            JSONObject jo = JSONObject.parseObject(componentMetaData);
            ObjectMapper om = new ObjectMapper();
            EnterpriseHonorComponent enterpriseHonorComponent = om.convertValue(jo, EnterpriseHonorComponent.class);
            picList.addAll(enterpriseHonorComponent.getHonorList());
        }
        return Message.success(picList);
    }

    public Message getEnterpriseAllFiles(String enterpriseId) {
        List<CardEnterpriseTemplateNew> cardEnterpriseTemplateNews = cardEnterpriseTemplateNewMapper.selectList(new LambdaQueryWrapper<CardEnterpriseTemplateNew>().eq(CardEnterpriseTemplateNew::getEnterpriseId, enterpriseId).eq(CardEnterpriseTemplateNew::getIsDelete, 0));
        if (cardEnterpriseTemplateNews.isEmpty()) {
            return Message.success(new ArrayList<>());
        }
        List<CardEnterpriseComponent> files = cardEnterpriseComponentMapper.selectList(new LambdaQueryWrapper<CardEnterpriseComponent>().in(CardEnterpriseComponent::getTemplateId, cardEnterpriseTemplateNews.stream().map(CardEnterpriseTemplateNew::getBaseId).collect(Collectors.toList())).eq(CardEnterpriseComponent::getComponentType, "File").orderByAsc(CardEnterpriseComponent::getSort));
        if (files.isEmpty()) {
            return Message.success(new ArrayList<>());
        }
        List<EnterpriseFile> fileList = getAllFilesFromComponent(files);
        return Message.success(fileList);
    }

    public Message getPersonalAllFiles(String userId) {
        List<CardEnterpriseTemplateNew> cardEnterpriseTemplateNews = cardEnterpriseTemplateNewMapper.selectList(new LambdaQueryWrapper<CardEnterpriseTemplateNew>().eq(CardEnterpriseTemplateNew::getBaseCreateBy, userId).isNull(CardEnterpriseTemplateNew::getEnterpriseId).eq(CardEnterpriseTemplateNew::getIsDelete, 0));
        if (cardEnterpriseTemplateNews.isEmpty()) {
            return Message.success(new ArrayList<>());
        }
        List<CardEnterpriseComponent> files = cardEnterpriseComponentMapper.selectList(new LambdaQueryWrapper<CardEnterpriseComponent>().in(CardEnterpriseComponent::getTemplateId, cardEnterpriseTemplateNews.stream().map(CardEnterpriseTemplateNew::getBaseId).collect(Collectors.toList())).eq(CardEnterpriseComponent::getComponentType, "File").orderByAsc(CardEnterpriseComponent::getSort));
        if (files.isEmpty()) {
            return Message.success(new ArrayList<>());
        }
        List<EnterpriseFile> fileList = getAllFilesFromComponent(files);
        return Message.success(fileList);
    }

    private List<EnterpriseFile> getAllFilesFromComponent(List<CardEnterpriseComponent> componentList) {
        List<EnterpriseFile> fileList = new ArrayList<>();
        for (CardEnterpriseComponent file : componentList) {
            String componentMetaData = file.getComponentMetaData();
            JSONObject jo = JSONObject.parseObject(componentMetaData);
            ObjectMapper om = new ObjectMapper();
            EnterpriseFileComponent enterpriseFileComponent = om.convertValue(jo, EnterpriseFileComponent.class);
            fileList.addAll(enterpriseFileComponent.getFileList());
        }
        return fileList;
    }

    public List<CardMemberDataVo> getMemberDataByTemplate(CardBaseInfoDto dto, Page<CardMemberDataVo> page) {
        List<CardMemberDataVo> cardMemberDataVos = new ArrayList<>();
        if (StrUtil.isNotEmpty(dto.getEnterpriseId())) {
            // 企业版
            cardMemberDataVos = cardPersonalBaseInfoMapper.selectMemberDataByTemplate(dto, page);
        } else if (StrUtil.isNotEmpty(dto.getBaseId())) {
            // 个人版
            cardMemberDataVos = cardUserCardSettingMapper.selectMemberDataByTemplate(dto, page);
        }
        return cardMemberDataVos;
    }

    public List<CardEnterpriseTemplateVo> getTemplateUsingData(CardBaseInfoDto dto, Page<CardEnterpriseTemplateVo> page) {
        return cardPersonalBaseInfoMapper.selectTemplateUsingData(dto, page);
    }

    public List<CardUserTemplateVo> getPersonalTemplateUsingData(String userId, Page<CardUserTemplateVo> page) {
        return cardUserCardSettingMapper.getPersonalTemplateUsingData(userId, page);
    }

    public void exportMemberDataByTemplate(HttpServletResponse response, CardBaseInfoDto dto) throws IOException {
        Workbook book = null;
        ExcelWriter excelWriter;
        ServletOutputStream outputStream = null;
        int rowIndex = 0;
        try {
            book = WorkbookUtil.createBook(true);
            excelWriter = new ExcelWriter(book, "员工数据");
            List<CardMemberDataVo> dataList = this.getMemberDataByTemplate(dto, null);
            if (dataList.isEmpty()) {
                Message message = Message.fail("导出失败");
                ResponseUtil.sendJsonString(response, JSONObject.toJSONString(message));
            } else {
                if (StrUtil.isNotEmpty(dto.getBaseId())) {
                    // 个人版
                    excelWriter.writeCellValue(0, rowIndex, "姓名"); // 参数顺序：列索引，行索引，单元格值
                    excelWriter.writeCellValue(1, rowIndex, "职位");
                    excelWriter.writeCellValue(2, rowIndex, "手机号");
                    excelWriter.writeCellValue(3, rowIndex, "应用模板");
                    excelWriter.writeCellValue(4, rowIndex, "转发次数");
                    excelWriter.writeCellValue(5, rowIndex, "被访问次数");
                    excelWriter.writeCellValue(6, rowIndex, "交换名片数");
                    excelWriter.writeCellValue(7, rowIndex, "收藏名片数");
                    rowIndex++;
                    for (CardMemberDataVo data : dataList) {
                        excelWriter.writeCellValue(0, rowIndex, data.getName());
                        excelWriter.writeCellValue(1, rowIndex, data.getPositionOne());
                        excelWriter.writeCellValue(2, rowIndex, data.getUsername());
                        excelWriter.writeCellValue(3, rowIndex, data.getTemplateName());
                        excelWriter.writeCellValue(4, rowIndex, data.getShareNum());
                        excelWriter.writeCellValue(5, rowIndex, data.getViewNum());
                        excelWriter.writeCellValue(6, rowIndex, data.getExchangeNum());
                        excelWriter.writeCellValue(7, rowIndex, data.getCollectNum());
                        rowIndex++;
                    }
                } else {
                    // 企业版
                    CardEnterpriseTemplate cardEnterpriseTemplate = cardEnterpriseTemplateMapper.queryEnterpriseTemplateInfo(dataList.get(0).getTemplateId());
                    List<CardTemplateStyleFieldBo> cardTemplateStyleFields = cardTemplateStyleFieldMapper.queryListByOldTemplateId(cardEnterpriseTemplate.getBaseId());
                    List<String> fieldNameList = this.buildFieldNameList(cardTemplateStyleFields);
                    for (int i = 0; i < fieldNameList.size(); i++) {
                        excelWriter.writeCellValue(i, rowIndex, fieldNameList.get(i)); // 参数顺序：列索引，行索引，单元格值
                    }
                    rowIndex++;
                    for (CardMemberDataVo data : dataList) {
                        List<CardStyleFieldData> cardStyleFieldDataList = cardStyleFieldDataMapper.queryListByCardId(data.getBaseId());
                        for (int columnIndex = 0; columnIndex < cardTemplateStyleFields.size(); columnIndex++) {
                            String fieldId = cardTemplateStyleFields.get(columnIndex).getBaseId();
                            String fieldValue = this.findExcelValue(fieldId, cardStyleFieldDataList);
                            excelWriter.writeCellValue(columnIndex, rowIndex, fieldValue);
                        }
                        excelWriter.writeCellValue(cardTemplateStyleFields.size(), rowIndex, data.getTemplateName());
                        excelWriter.writeCellValue(cardTemplateStyleFields.size() + 1, rowIndex, data.getShareNum());
                        excelWriter.writeCellValue(cardTemplateStyleFields.size() + 2, rowIndex, data.getViewNum());
                        excelWriter.writeCellValue(cardTemplateStyleFields.size() + 3, rowIndex, data.getExchangeNum());
                        excelWriter.writeCellValue(cardTemplateStyleFields.size() + 4, rowIndex, data.getCollectNum());
                        rowIndex++;
                    }
                }
                String encodedFileName = URLEncoder.encode("员工数据.xlsx", "UTF-8").replaceAll("\\+", "%20");
                response.setContentType("application/vnd.ms-excel;charset=utf-8");
                response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);
                outputStream = response.getOutputStream();
                excelWriter.flush(outputStream, true);
                excelWriter.close();
            }
        } catch (Exception e) {
            log.error("导出异常：{}", ExceptionUtil.stacktraceToString(e));
            Message message = Message.fail("导出异常");
            ResponseUtil.sendJsonString(response, JSONObject.toJSONString(message));
        } finally {
            IoUtil.close(book);
            IoUtil.close(outputStream);
        }
    }

    @Transactional(rollbackFor = Throwable.class)
    public Message changeAdminAccount(CardUserManagementDto dto) {
        String adminAccount = dto.getAdminAccount();
        String newAdminAccount = dto.getNewAdminAccount();
        String enterpriseId = dto.getEnterpriseId();
        // 查询系统当前是否存在转让后的账号，若不存在则先进行账号的创建
        String userId = cardAdminBackendMapper.selectUserId(newAdminAccount);
        if (StrUtil.isEmpty(userId)) {
            // 创建账号
            userId = UUIDUtil.getUUID2();
            cardAdminBackendMapper.createUser(userId, newAdminAccount, Md5Util.hash(newAdminAccount));
        }
        if (StrUtil.isNotBlank(adminAccount)) {
            // 删除原账号的管理员角色
            cardAdminBackendMapper.deleteAdminAccountRole(enterpriseId);
            if (dto.getChangeMode() == 2) {
                // 当变更模式为移除原账号时
                String userid = cardAdminBackendMapper.selectUserId(adminAccount);
                // 删除原账号在该企业的企业名片
                cardPersonalBaseInfoMapper.update(null, new LambdaUpdateWrapper<CardBaseInfo>().eq(CardBaseInfo::getUserId, userid).eq(CardBaseInfo::getEnterpriseId, enterpriseId).set(CardBaseInfo::getIsDelete, 1).set(CardBaseInfo::getBaseUpdateTime, new Date()));
                // 删除原账号与企业的关联关系
                luLianEnterpriseUserMapper.delete(new LambdaQueryWrapper<LuLianEnterpriseUser>().eq(LuLianEnterpriseUser::getUserId, userid).eq(LuLianEnterpriseUser::getEnterpriseId, enterpriseId));
            }
        }
        // 创建管理员角色
        cardAdminBackendMapper.createUserRole(UUIDUtil.getUUID2(), userId, "043ea2e3e02c4aa591df1f83e65069bc", enterpriseId);
        // 创建与企业的关联关系
        luLianEnterpriseUserMapper.insert(LuLianEnterpriseUser.builder().enterpriseId(enterpriseId).userId(userId).build());
        return Message.success("操作成功");
    }

    public Message changeEnterprisePrivileges(CardUserManagementDto dto) throws ParseException {
        String enterpriseId = dto.getEnterpriseId();
        LuLianEnterprise luLianEnterprise = luLianEnterpriseMapper.selectById(enterpriseId);
        if (luLianEnterprise != null) {
            LambdaUpdateWrapper<LuLianEnterprise> updateWrapper = new LambdaUpdateWrapper<LuLianEnterprise>().eq(LuLianEnterprise::getBaseId, enterpriseId);
            if (StrUtil.isNotBlank(dto.getVersion()) && dto.getExpireTime() != null) {
                updateWrapper.set(LuLianEnterprise::getMiniProgramVersion, Integer.valueOf(dto.getVersion()))
                        .set(luLianEnterprise.getMiniProgramVersion() != null, LuLianEnterprise::getExpireTime, dto.getExpireTime());
                // 同步更新当前企业下的企业名片数据
                cardPersonalBaseInfoMapper.update(null, new LambdaUpdateWrapper<CardBaseInfo>().eq(CardBaseInfo::getEnterpriseId, enterpriseId).eq(CardBaseInfo::getIsDelete, 0)
                        .set(CardBaseInfo::getCardVersion, "1".equals(dto.getVersion()) ? "3" : "2".equals(dto.getVersion()) ? "4" : "5")
                        .set(CardBaseInfo::getExpireTime, dto.getExpireTime()));
            }
            updateWrapper.set((StrUtil.isNotBlank(dto.getQualificationRecognitionType()) && StrUtil.isNotBlank(dto.getQualificationRecognitionPic())), LuLianEnterprise::getQualificationRecognitionType, dto.getQualificationRecognitionType())
                    .set((StrUtil.isNotBlank(dto.getQualificationRecognitionType()) && StrUtil.isNotBlank(dto.getQualificationRecognitionPic())), LuLianEnterprise::getQualificationRecognitionPic, dto.getQualificationRecognitionPic());
            luLianEnterpriseMapper.update(null, updateWrapper);
            if ("5".equals(dto.getVersion())) {
                // 若变更为拓客版
                if (dto.getLinkCount() == null) {
                    return Message.fail("若变更为拓客版，须填写解锁次数");
                }
                GxmhEnterpriseLinkCount gxmhEnterpriseLinkCount = gxmhEnterpriseLinkCountMapper.selectOne(new LambdaQueryWrapper<GxmhEnterpriseLinkCount>().eq(GxmhEnterpriseLinkCount::getEnterpriseId, enterpriseId));
                if (gxmhEnterpriseLinkCount == null) {
                    gxmhEnterpriseLinkCount = new GxmhEnterpriseLinkCount();
                    gxmhEnterpriseLinkCount.setBaseId(UUIDUtil.getUUID2());
                    gxmhEnterpriseLinkCount.setEnterpriseId(enterpriseId);
                    gxmhEnterpriseLinkCount.setLinkCount(dto.getLinkCount());
                    gxmhEnterpriseLinkCount.setBaseCreateTime(new Date());
                    gxmhEnterpriseLinkCountMapper.insert(gxmhEnterpriseLinkCount);
                } else {
                    gxmhEnterpriseLinkCountMapper.update(gxmhEnterpriseLinkCount, new LambdaUpdateWrapper<GxmhEnterpriseLinkCount>().eq(GxmhEnterpriseLinkCount::getEnterpriseId, enterpriseId)
                        .set(GxmhEnterpriseLinkCount::getLinkCount, dto.getLinkCount()).set(GxmhEnterpriseLinkCount::getBaseCreateTime, new Date()));
                }
            }
        } else {
            if ("4".equals(dto.getVersion())) {
                showEnterpriseTrialMapper.update(null, new LambdaUpdateWrapper<ShowEnterpriseTrial>().eq(ShowEnterpriseTrial::getBaseId, enterpriseId)
                        .set(ShowEnterpriseTrial::getMiniProgramVersion, 4).set(dto.getExpireTime() != null, ShowEnterpriseTrial::getExpireTime, dto.getExpireTime()));
                // 同步更新当前企业下的企业名片数据
                cardPersonalBaseInfoMapper.update(null, new LambdaUpdateWrapper<CardBaseInfo>().eq(CardBaseInfo::getEnterpriseId, enterpriseId).eq(CardBaseInfo::getIsDelete, 0)
                        .set(CardBaseInfo::getExpireTime, dto.getExpireTime()));
            } else {
                // 变更为正式版（基础版、高级版、拓客版），将试用版的企业数据迁移至正式企业表，并删除试用版企业数据
                ShowEnterpriseTrial showEnterpriseTrial = showEnterpriseTrialMapper.selectById(enterpriseId);
                LuLianEnterprise enterprise = new LuLianEnterprise();
                BeanUtils.copyProperties(showEnterpriseTrial, enterprise);
                enterprise.setMiniProgramVersion(Integer.valueOf(dto.getVersion()));
                enterprise.setExpireTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dto.getExpireTime()));
                if (StrUtil.isNotBlank(dto.getQualificationRecognitionType()) && StrUtil.isNotBlank(dto.getQualificationRecognitionPic())) {
                    enterprise.setQualificationRecognitionType(dto.getQualificationRecognitionType());
                    enterprise.setQualificationRecognitionPic(dto.getQualificationRecognitionPic());
                }
                enterprise.setBaseCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                luLianEnterpriseMapper.insert(enterprise);
                // 若变更为拓客版则保存拓客版解锁次数
                if ("5".equals(dto.getVersion())) {
                    GxmhEnterpriseLinkCount gxmhEnterpriseLinkCount = new GxmhEnterpriseLinkCount();
                    gxmhEnterpriseLinkCount.setBaseId(UUIDUtil.getUUID2());
                    gxmhEnterpriseLinkCount.setEnterpriseId(enterpriseId);
                    if (dto.getLinkCount() == null) {
                        return Message.fail("若变更为拓客版，须填写解锁次数");
                    }
                    gxmhEnterpriseLinkCount.setLinkCount(dto.getLinkCount());
                    gxmhEnterpriseLinkCount.setBaseCreateTime(new Date());
                    gxmhEnterpriseLinkCountMapper.insert(gxmhEnterpriseLinkCount);
                }
                // 删除试用版企业数据
                showEnterpriseTrialMapper.deleteById(enterpriseId);

                // 同步更新当前企业下的企业名片数据
                cardPersonalBaseInfoMapper.update(null, new LambdaUpdateWrapper<CardBaseInfo>().eq(CardBaseInfo::getEnterpriseId, enterpriseId).eq(CardBaseInfo::getIsDelete, 0)
                        .set(CardBaseInfo::getCardVersion, "1".equals(dto.getVersion()) ? "3" : "2".equals(dto.getVersion()) ? "4" : "5")
                        .set(CardBaseInfo::getExpireTime, dto.getExpireTime()));
            }
        }
        return Message.success("操作成功");
    }

    public Map<String, Object> getEnterprisePrivileges(String enterpriseId) {
        Map<String, Object> result = new HashMap<>();
        LuLianEnterprise enterprise = luLianEnterpriseMapper.selectById(enterpriseId);
        if (enterprise != null) {
            result.put("version", String.valueOf(enterprise.getMiniProgramVersion()));
            result.put("expireTime", enterprise.getExpireTime());
            if (enterprise.getMiniProgramVersion() == 5) {
                GxmhEnterpriseLinkCount gxmhEnterpriseLinkCount = gxmhEnterpriseLinkCountMapper.selectOne(new LambdaQueryWrapper<GxmhEnterpriseLinkCount>().eq(GxmhEnterpriseLinkCount::getEnterpriseId, enterpriseId));
                if (gxmhEnterpriseLinkCount != null) {
                    result.put("linkCount", gxmhEnterpriseLinkCount.getLinkCount());
                } else {
                    result.put("linkCount", null);
                }
            } else {
                result.put("linkCount", null);
            }
            result.put("qualificationRecognitionType", enterprise.getQualificationRecognitionType());
            result.put("qualificationRecognitionPic", enterprise.getQualificationRecognitionPic());
        } else {
            ShowEnterpriseTrial showEnterpriseTrial = showEnterpriseTrialMapper.selectById(enterpriseId);
            result.put("version", String.valueOf(showEnterpriseTrial.getMiniProgramVersion()));
            result.put("expireTime", showEnterpriseTrial.getExpireTime());
            result.put("linkCount", null);
            result.put("qualificationRecognitionType", null);
            result.put("qualificationRecognitionPic", null);
        }
        return result;
    }

    private List<String> buildFieldNameList(List<CardTemplateStyleFieldBo> cardTemplateStyleFields) {
        List<String> fieldList = new ArrayList<>();
        for(CardTemplateStyleFieldBo cardTemplateStyleField : cardTemplateStyleFields) {
            String name = cardTemplateStyleField.getBaseName();
            if (cardTemplateStyleField.getRequiredFlag()) {
                fieldList.add(name + MUST_FILL);
            } else {
                fieldList.add(name);
            }
        }
        fieldList.add("应用模板");
        fieldList.add("转发次数");
        fieldList.add("被访问次数");
        fieldList.add("交换名片数");
        fieldList.add("收藏名片数");
        return fieldList;
    }

    private String findExcelValue(String fieldId, List<CardStyleFieldData> cardStyleFieldDataList) {
        for (CardStyleFieldData CardStyleFieldData : cardStyleFieldDataList) {
            if(fieldId.equals(CardStyleFieldData.getStyleFieldId())) {
                return CardStyleFieldData.getStyleFieldValue();
            }
        }
        return "";
    }

    public void addExportRecord(CardAdminExportRecordDto dto) {
        CardAdminExportRecord cardAdminExportRecord = new CardAdminExportRecord();
        BeanUtils.copyProperties(dto, cardAdminExportRecord);
        cardAdminExportRecord.setBaseId(UUIDUtil.getUUID2());
        cardAdminExportRecord.setCreator(dto.getUserId());
        cardAdminExportRecord.setBaseCreateTime(new Date());
        cardAdminExportRecordMapper.insert(cardAdminExportRecord);
    }
}